home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
ACORNUSERS
/
EMULATOR
/
MAGICKIT
/
assembler
/
c
/
symbol
< prev
Wrap
Text File
|
1998-04-14
|
3KB
|
178 lines
#include <stdio.h>
#include "defs.h"
#include "externs.h"
/* colsym() collects a symbol from prlnbuf into symbol[],
* leaves prlnbuf pointer at first invalid symbol character,
* returns 0 if no symbol collected
*/
int colsym(int *ip)
{
int valid;
int i;
char c;
valid = 1;
i = 0;
while (valid == 1) {
c = prlnbuf[*ip];
if (c == '_' || c == '.');
else if (c >= 'a' && c <= 'z');
else if (c >= 'A' && c <= 'Z');
else if (i >= 1 && c >= '0' && c <= '9');
else valid = 0;
if (valid == 1) {
if (i < SBOLSZ - 1)
symbol[++i] = c;
(*ip)++;
}
}
if (i == 1) {
switch (symbol[1]) {
case 'A': case 'a':
case 'X': case 'x':
case 'Y': case 'y':
error("Symbol is reserved (A, X or Y)!");
i = 0;
}
}
symbol[0] = i;
symbol[i+1] = '\0';
return(i);
}
/* symbol table lookup
* if found, return pointer to symbol
* else, install symbol as undefined, and return pointer
*/
struct t_symbol *stlook(void)
{
struct t_symbol *ptr;
unsigned int hash = 0;
char c;
int i;
if (symbol[1] == '.'){ /* Local symbol */
if (glablptr) {
ptr = glablptr->local;
while (ptr) {
if (!strcmp(symbol, ptr->name))
break;
ptr = ptr->next;
}
if (ptr == NULL)
ptr = stinstal(hash, 1);
} else {
error("Local symbol not allowed!");
return (NULL);
}
} else { /* Global symbol */
for (i = 0; i < symbol[0]; i++) {
c = symbol[i + 1];
hash += c;
hash = (hash << 3) + (hash >> 5) + c;
}
hash &= 0xFF;
ptr = hash_tbl[hash];
while (ptr) {
if (!strcmp(symbol, ptr->name))
break;
ptr = ptr->next;
}
if (ptr == NULL)
ptr = stinstal(hash, 0);
}
return(ptr);
}
/* install symbol into symtab */
struct t_symbol *stinstal(int hash, int type)
{
struct t_symbol *ptr;
if ((ptr = (void *)malloc(sizeof(struct t_symbol))) == NULL) {
error("Out of memory!");
return (NULL);
}
ptr->type = UNDEF;
ptr->value = 0;
ptr->local = NULL;
ptr->bank = -1;
ptr->page = -1;
strcpy(ptr->name, symbol);
if (type >= 1) {
ptr->next = glablptr->local;
glablptr->local = ptr;
} else {
ptr->next = hash_tbl[hash];
hash_tbl[hash] = ptr;
}
return(ptr);
}
/* remove the latest defined symbol from symtab */
int stremove(void)
{
char c;
int i, hash = 0;
for (i = 0; i < symbol[0]; i++) {
c = symbol[i + 1];
hash += c;
hash = (hash << 3) + (hash >> 5) + c;
}
hash &= 0xFF;
if (hash_tbl[hash] != lablptr) {
error("Internal error[2]!");
return (0);
}
hash_tbl[hash] = lablptr->next;
free(lablptr);
return (1);
}
/* assign <value> to label pointed to by lablptr,
* checking for valid definition, etc.
*/
int labldef(int lval, int flag)
{
char c;
int i;
if (lablptr) {
if (flag)
lval = (lval & 0x1FFF) | (page << 13);
if (pass == FIRST_PASS) {
if (lablptr->type == UNDEF) {
lablptr->type = DEFABS;
lablptr->value = lval;
} else {
lablptr->type = MDEF;
lablptr->value = 0;
error("Label multiply defined!");
return(-1);
}
} else {
if ((lablptr->value != lval) && (pass == LAST_PASS)) {
error("Internal error[1]!");
return(-1);
}
}
if (flag) {
lablptr->bank = bank;
lablptr->page = page;
c = lablptr->name[1];
if (c != '.')
glablptr = lablptr;
}
}
return(0);
}